package com.cardone.platform.usercenter.service;

import com.cardone.common.dto.PaginationDto;
import com.cardone.context.ContextHolder;
import com.cardone.context.DictionaryException;
import com.cardone.platform.common.dto.EntityLogDto;
import com.cardone.platform.common.service.EntityLogService;
import com.cardone.platform.usercenter.dao.UserDao;
import com.cardone.platform.usercenter.dto.UserDto;
import com.cardone.platform.usercenter.po.User;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

/**
 * 用户服务
 *
 * @author yaohaitao
 */
@Getter
@Setter
@Transactional(readOnly = true)
public class UserDefaultService extends com.cardone.common.service.SimpleDefaultService<com.cardone.platform.usercenter.dto.UserDto> implements UserService {
    @Override
    public UserDao getDao() {
        return ContextHolder.getBean(UserDao.class);
    }

    @Override
    @Transactional(readOnly = true)
    public Integer readByCodeNqIdForCount(final UserDto readUser) {
        return ContextHolder.getBean(UserDao.class).readByCodeNqIdForCount(readUser);
    }

    @Override
    @Transactional(readOnly = true)
    public <P> P findById(final Class<P> mappedClass, final UserDto findUser, String... selectNames) {
        if (StringUtils.isBlank(findUser.getId()) && StringUtils.isNotBlank(findUser.getLoginKey())) {
            final String userId = ContextHolder.getBean(EntityLogService.class).readEntityIdByIdForValid(findUser.getLoginKey());

            findUser.setId(userId);
        }

        return ContextHolder.getBean(UserDao.class).findById(mappedClass, findUser, selectNames);
    }

    @Override
    @Transactional
    public UserDto saveByCode(final UserDto saveUser) {
        if (StringUtils.isBlank(saveUser.getCode())) {
            throw new DictionaryException("用户名不能为空值").setTypeCode(User.class).setCode("isBlankCode");
        }

        if (StringUtils.isBlank(saveUser.getPassword())) {
            throw new DictionaryException("密码不能为空值").setTypeCode(User.class).setCode("isBlankPassword");
        }

        final Integer userCount = ContextHolder.getBean(UserService.class).readByCodeNqIdForCount(saveUser);

        if (userCount > 0) {
            throw new DictionaryException("用户名已有，请修改用户名").setTypeCode(User.class).setCode("provenCode");
        }

        final String md5Password = DigestUtils.md5Hex(saveUser.getPassword());

        saveUser.setPassword(md5Password);

        ContextHolder.getBean(UserDao.class).insertByCode(saveUser);

        final UserDto user = ContextHolder.getBean(UserDao.class).findByCodeOrId(UserDto.class, saveUser);

//        ContextHolder.getBean(RoleUserService.class).insertByRoleCode(saveUser.getRoleCodeList(), user.getId());

        return user;
    }

    @Override
    @Transactional
    public UserDto login(final UserDto loginUser) {
        return login(loginUser, null);
    }

    @Override
    public UserDto login(UserDto loginUser, String host) {
        if (StringUtils.isBlank(loginUser.getCode())) {
            throw new DictionaryException("登录名不能为空");
        }

        if (StringUtils.isBlank(loginUser.getPassword())) {
            throw new DictionaryException("密码不能为空");
        }

        loginUser.setNewPassword(DigestUtils.md5Hex(loginUser.getPassword()));

        UserDto user = ContextHolder.getBean(UserService.class).findByCodeForLogin(UserDto.class, loginUser);

        if (user == null) {
            return null;
        }

        user.setLoginKey(UUID.randomUUID().toString());

        final EntityLogDto insertEntityLog = EntityLogDto.newEntityLog();

        insertEntityLog.setId(user.getLoginKey());
        insertEntityLog.setTypeTypeCode("log_type");
        insertEntityLog.setTypeCode("login");
        insertEntityLog.setCode("login");
        insertEntityLog.setUserId(user.getId());
        insertEntityLog.setEntityId(user.getId());

        ContextHolder.getBean(EntityLogService.class).insertByCode(insertEntityLog);

        com.cardone.common.cache.util.CacheUtils.get(EntityLogService.class.getName()).put("readEntityIdByIdForValid:" + user.getLoginKey(), user.getId());

        return user;
    }

    @Override
    @Transactional
    public UserDto register(final UserDto registerUser) {
        final UserDto loginUser = this.saveByCode(registerUser);

        final UserDto user = ContextHolder.getBean(UserService.class).findById(loginUser);

        user.setLoginKey(UUID.randomUUID().toString());

        final EntityLogDto insertEntityLog = EntityLogDto.newEntityLog();

        insertEntityLog.setId(user.getLoginKey());
        insertEntityLog.setTypeTypeCode("log_type");
        insertEntityLog.setTypeCode("login");
        insertEntityLog.setCode("login");
        insertEntityLog.setUserId(user.getId());
        insertEntityLog.setEntityId(user.getId());

        ContextHolder.getBean(EntityLogService.class).insertByCode(insertEntityLog);

        return user;
    }

    @Override
    @Transactional
    public int updateEndDateByIdForInvalid(final String id) {
        return ContextHolder.getBean(UserDao.class).updateEndDateByIdForInvalid(id);
    }

    @Override
    @Transactional(readOnly = true)
    public UserDto findById(final UserDto findUser) {
        return ContextHolder.getBean(UserService.class).findById(UserDto.class, findUser);
    }

    @Override
    @Transactional(readOnly = true)
    public UserDto findById(final String id) {
        if (StringUtils.isBlank(id)) {
            throw new DictionaryException("用户标识不能为空值").setTypeCode("user").setCode("idIsNotBlank");
        }

        return ContextHolder.getBean(UserDao.class).findById(id);
    }

    @Override
    @Transactional(readOnly = true)
    public <P> P findByCodeForLogin(final Class<P> mappedClass, final UserDto findUser) {
        return ContextHolder.getBean(UserDao.class).findByCodeForLogin(mappedClass, findUser);
    }


    @Override
    @Transactional(readOnly = true)
    public <P> PaginationDto<P> paginationByOrgIdAndLikeCode(final Class<P> mappedClass, final UserDto paginationUser) {
        return ContextHolder.getBean(UserDao.class).paginationByOrgIdAndLikeCode(mappedClass, paginationUser);
    }

    @Override
    @Transactional
    public int updatePasswordById(final String id, final String newPassword) {
        if (StringUtils.isBlank(id)) {
            throw new DictionaryException("用户标识不能为空值").setTypeCode(User.class).setCode("isBlankId");
        }

        if (StringUtils.isBlank(newPassword)) {
            throw new DictionaryException("新密码不能为空值").setTypeCode(User.class).setCode("isBlankNewPassword");
        }

        final String md5NewPassword = DigestUtils.md5Hex(newPassword);

        final int updateCount = ContextHolder.getBean(UserDao.class).updatePasswordById(id, null, md5NewPassword);

        if (updateCount < 1) {
            throw new DictionaryException("用户标识不正确").setTypeCode(User.class).setCode("notId");
        }

        return updateCount;
    }

    @Override
    @Transactional
    public int updatePasswordById(final String id, final String oldPassword, final String newPassword) {
        return this.updatePasswordById(id, oldPassword, newPassword, true);
    }

    @Override
    @Transactional
    public int updatePasswordById(final String id, final String oldPassword, final String newPassword, final Boolean isDiges) {
        if (StringUtils.isBlank(id)) {
            throw new DictionaryException("用户标识不能为空值").setTypeCode(User.class).setCode("isBlankId");
        }

        if (StringUtils.isBlank(newPassword)) {
            throw new DictionaryException("新密码不能为空值").setTypeCode(User.class).setCode("isBlankNewPassword");
        }

        String md5OldPassword = oldPassword;

        if (StringUtils.isNotBlank(oldPassword) && BooleanUtils.isTrue(isDiges)) {
            md5OldPassword = DigestUtils.md5Hex(oldPassword);
        }

        String md5NewPassword = newPassword;

        if (BooleanUtils.isTrue(isDiges)) {
            md5NewPassword = DigestUtils.md5Hex(newPassword);
        }

        final int updateCount = ContextHolder.getBean(UserDao.class).updatePasswordById(id, md5OldPassword, md5NewPassword);

        if (updateCount < 1) {
            throw new DictionaryException("旧密码不正确").setTypeCode(User.class).setCode("notOldPassword");
        }

        return updateCount;
    }

    @Override
    @Transactional
    public int updateForBaseInfo(final UserDto updateUser, final Boolean updateMobilePhone) {
        if (StringUtils.isBlank(updateUser.getId())) {
            throw new DictionaryException("用户标识不能为空值").setTypeCode(User.class).setCode("isBlankId");
        }

        return ContextHolder.getBean(UserDao.class).updateForBaseInfo(updateUser, updateMobilePhone);
    }

    @Override
    @Transactional
    public int updateForFullInfo(final UserDto updateUser, final Boolean updateMobilePhone) {
        if (StringUtils.isBlank(updateUser.getId())) {
            throw new DictionaryException("用户标识不能为空值").setTypeCode(User.class).setCode("isBlankId");
        }

        return ContextHolder.getBean(UserDao.class).updateForFullInfo(updateUser, updateMobilePhone);
    }

    @Override
    @Transactional
    public int updateForDetail(final UserDto updateUser) {
        if (StringUtils.isBlank(updateUser.getId())) {
            throw new DictionaryException("用户标识不能为空值").setTypeCode(User.class).setCode("isBlankId");
        }

        if (StringUtils.isNotBlank(updateUser.getPassword())) {
            final String md5Password = DigestUtils.md5Hex(updateUser.getPassword());

            updateUser.setPassword(md5Password);
        }

        return ContextHolder.getBean(UserDao.class).updateForDetail(updateUser);
    }

    @Override
    @Transactional
    public int updateMobilePhone(final String id, final String mobilePhone) {
        return ContextHolder.getBean(UserDao.class).updateMobilePhone(id, mobilePhone);
    }
}